package com.zhang.controller;

import com.zhang.entity.Redisuser;
import com.zhang.service.IUserService;
import com.zhang.util.RandomValidateCode;
import com.zhang.util.RedisKeyUtils;
import com.zhang.util.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.TimeoutUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author zhang
 * @time 2022/01/24 20:54:42
 */
@RestController
public class UserController {
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate redisTemplate;

    private String remoteIp;

    @PostMapping("user/save")
    public ResultVO save(@RequestBody Redisuser user) {
        userService.save(user);
        return ResultVO.success("添加成功");
    }

    @PostMapping("user/login")
    public ResultVO login(@RequestBody Redisuser user) {
        String logFailKey = RedisKeyUtils.loginFailKeyName(user.getUsername());
        String frozenKey = RedisKeyUtils.frozenUserKeyName(user.getUsername());

        Redisuser loginUser = userService.login(user.getUsername(), user.getPassword());
        if (loginUser == null) {
            //只要登录失败就在redis中记录当前 是第几次登录失败

            //先判断当前 是几次失败的登录  如果不存在键值以下的api才生效
            redisTemplate.opsForValue().setIfAbsent(logFailKey, "0", 2, TimeUnit.MINUTES);
            redisTemplate.opsForValue().increment(logFailKey);
            //如果登录 失败次数达到5次 就冻结账户
            String failTimes = (String) redisTemplate.opsForValue().get(logFailKey);
            if (Integer.valueOf(failTimes) >= 5) {
                redisTemplate.opsForValue().setIfAbsent(frozenKey, "", 1, TimeUnit.HOURS);
                return ResultVO.failure("登录失败次数，达到5次，账户已冻结");

            }
            return ResultVO.failure("登录失败" + failTimes + "次!");

        }
        return ResultVO.success("登录成功");


    }

    @GetMapping("user/getCode")
    public void getCode(HttpServletRequest request, HttpServletResponse response){
        response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
        response.setHeader("Pragma", "No-cache");//设置响应头信息，告诉浏览器不要缓存此内容
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);

        RandomValidateCode randomValidateCode = new RandomValidateCode();
        // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(95, 25, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        g.fillRect(0, 0, 95, 25);
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
        g.setColor(randomValidateCode.getRandColor(110, 133));
        // 绘制干扰线
        for (int i = 0; i <= 40; i++) {
            randomValidateCode.drowLine(g);
        }
        // 绘制随机字符
        String randomString = "";
        for (int i = 1; i <= 4; i++) {
            randomString = randomValidateCode.drowString(g, randomString, i);
        }
        // 生产验证码字符串并保存到 Redis 中，ip-rightCode，有效期为 1 小时
        remoteIp = request.getRemoteAddr();
        redisTemplate.opsForValue().set(remoteIp, randomString, 60, TimeUnit.SECONDS);
        g.dispose();
        try {
            // 将内存中的图片通过流动形式输出到客户端
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    @PostMapping("user/validateCode")
    public ResultVO validateCode(@RequestBody String code){
        String userCode = (String)redisTemplate.opsForValue().get(remoteIp);
        if (userCode == null){
            return ResultVO.failure("验证码已过期，请刷新再试");
        }
        if (code.equalsIgnoreCase(userCode)){
            //前端得到205后才会发起真正的login请求
            return new ResultVO(205, "验证成功", null);

        }
        return ResultVO.failure("验证码错误，请重新输入");

    }



}
